Skip to content

Internalize closure example jsfiddle #39728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions files/en-us/web/javascript/guide/closures/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ init();

`init()` creates a local variable called `name` and a function called `displayName()`. The `displayName()` function is an inner function that is defined inside `init()` and is available only within the body of the `init()` function. Note that the `displayName()` function has no local variables of its own. However, since inner functions have access to the variables of outer scopes, `displayName()` can access the variable `name` declared in the parent function, `init()`.

Run the code using [this JSFiddle link](https://jsfiddle.net/3dxck52m/) and notice that the `console.log()` statement within the `displayName()` function successfully displays the value of the `name` variable, which is declared in its parent function. This is an example of _lexical scoping_, which describes how a parser resolves variable names when functions are nested. The word _lexical_ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available. Nested functions have access to variables declared in their outer scope.
If you run this code in your console, you can see that the `console.log()` statement within the `displayName()` function successfully displays the value of the `name` variable, which is declared in its parent function. This is an example of _lexical scoping_, which describes how a parser resolves variable names when functions are nested. The word _lexical_ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available. Nested functions have access to variables declared in their outer scope.

### Scoping with let and const

Expand Down Expand Up @@ -132,7 +132,7 @@ Here's the JavaScript:

```js
function makeSizer(size) {
return function () {
return () => {
document.body.style.fontSize = `${size}px`;
};
}
Expand All @@ -154,9 +154,10 @@ document.getElementById("size-16").onclick = size16;
<button id="size-12">12</button>
<button id="size-14">14</button>
<button id="size-16">16</button>
<p>This is some text that will change size when you click the buttons above.</p>
```

Run the code using [JSFiddle](https://jsfiddle.net/hotae160/).
{{EmbedLiveSample("practical closures", "", "200")}}

## Emulating private methods with closures

Expand Down Expand Up @@ -359,14 +360,14 @@ console.log(getX()); // 2

Prior to the introduction of the [`let`](/en-US/docs/Web/JavaScript/Reference/Statements/let) keyword, a common problem with closures occurred when you created them inside a loop. To demonstrate, consider the following example code.

```html
```html live-sample___closures_bad
<p id="help">Helpful notes will appear here</p>
<p>Email: <input type="text" id="email" name="email" /></p>
<p>Name: <input type="text" id="name" name="name" /></p>
<p>Age: <input type="text" id="age" name="age" /></p>
```

```js
```js example-bad live-sample___closures_bad
function showHelp(help) {
document.getElementById("help").textContent = help;
}
Expand All @@ -390,7 +391,7 @@ function setupHelp() {
setupHelp();
```

Try running the code in [JSFiddle](https://jsfiddle.net/v7gjv/8164/).
{{EmbedLiveSample("closures_bad", "", "200")}}

The `helpText` array defines three helpful hints, each associated with the ID of an input field in the document. The loop cycles through these definitions, hooking up an `onfocus` event to each one that shows the associated help method.

Expand All @@ -400,7 +401,14 @@ The reason for this is that the functions assigned to `onfocus` form closures; t

One solution in this case is to use more closures: in particular, to use a function factory as described earlier:

```js
```html hidden live-sample___closures_factory
<p id="help">Helpful notes will appear here</p>
<p>Email: <input type="text" id="email" name="email" /></p>
<p>Name: <input type="text" id="name" name="name" /></p>
<p>Age: <input type="text" id="age" name="age" /></p>
```

```js live-sample___closures_factory
function showHelp(help) {
document.getElementById("help").textContent = help;
}
Expand All @@ -427,7 +435,7 @@ function setupHelp() {
setupHelp();
```

Run the code using [this JSFiddle link](https://jsfiddle.net/v7gjv/9573/).
{{EmbedLiveSample("closures_factory", "", "200")}}

This works as expected. Rather than the callbacks all sharing a single lexical environment, the `makeHelpCallback` function creates _a new lexical environment_ for each callback, in which `help` refers to the corresponding string from the `helpText` array.

Expand Down